package com.axones.planningpoker.rest.service;

import java.util.List;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.restlet.data.Status;
import org.restlet.resource.Delete;
import org.restlet.resource.Post;
import org.restlet.resource.Put;
import org.restlet.resource.ServerResource;

import com.axones.planningpoker.bean.Project;
import com.axones.planningpoker.bean.ProjectUser;
import com.axones.planningpoker.bean.User;
import com.axones.planningpoker.dao.ProjectDAO;
import com.axones.planningpoker.dao.ProjectUserDAO;
import com.axones.planningpoker.dao.UserDAO;
import com.google.gson.Gson;

public class ProjectUserResource extends ServerResource {
	private static UserDAO userDao;
	private static ProjectDAO pDao;
	private static ProjectUserDAO puDao;
	private static Gson gson;

	public ProjectUserResource() {
		if (userDao == null) {
			userDao = new UserDAO();
		}
		if (pDao == null) {
			pDao = new ProjectDAO();
		}
		if (puDao == null) {
			puDao = new ProjectUserDAO();
		}
		if (gson == null) {
			gson = new Gson();
		}
	}

	@Post
	public String doCreate(String json) {
		ProjectUser projectUser = gson.fromJson(json, ProjectUser.class);

		List<ProjectUser> pus = puDao.getByProject(projectUser.getProjectId());

		Project project = null;

		for (ProjectUser pu : pus) {
			if (pu.getProfile().equals(ProjectUser.PROFILE_ADMIN)) {
				project = pDao.get(pu.getProjectId());
			}
		}

		User user = userDao.find(projectUser.getEmail());

		if (user == null) {
			user = new User();

			user.setDisplayName(projectUser.getEmail().split("@")[0]);
			user.setEmail(projectUser.getEmail());
			user.setPassword(generatePassword(6));

			long id = userDao.add(user);
			user.setId(id);

			sendMail(
					user.getEmail(),
					"you have been added to the project \"" + project.getName()
							+ "\" in the Axones Planning Poker app",
					"download the app on any mobile device you want (iPhone, Android, Blackberry-QNX) and start using it, just enter your email and the password : "
							+ user.getPassword() + " remember to change it.");
		} else {
			sendMail(user.getEmail(),
					"you have been added to the project \"" + project.getName()
							+ "\" in the Axones Planning Poker app",
					"connect to the application to start working on it.");
		}

		projectUser.setUserId(user.getId());

		puDao.add(projectUser);

		user.setProfile(projectUser.getProfile());

		return gson.toJson(user);
	}

	@Put
	public void doUpdate(String json) {
		ProjectUser projectUser = gson.fromJson(json, ProjectUser.class);

		String result = puDao.update(projectUser);

		if (result.equals("ok")) {
			setStatus(Status.SUCCESS_OK);
		} else if (result.equals("not.found")) {
			setStatus(Status.CLIENT_ERROR_NOT_FOUND);
		}
	}

	@Delete
	public void doDelete() {
		Long projectId = Long.parseLong((String) getRequest().getAttributes()
				.get("projectId"));
		Long userId = Long.parseLong((String) getRequest().getAttributes().get(
				"userId"));

		ProjectUser projectUser = new ProjectUser();

		projectUser.setProjectId(projectId);
		projectUser.setUserId(userId);

		puDao.delete(projectUser);

		setStatus(Status.SUCCESS_OK);
	}

	private void sendMail(String to, String subject, String message) {
		Properties props = new Properties();
		Session session = Session.getDefaultInstance(props, null);

		try {
			Message msg = new MimeMessage(session);
			msg
					.setFrom(new InternetAddress(
							"zeth.bw@gmail.com"));
			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
			msg.setSubject(subject);
			msg.setText(message);
			Transport.send(msg);
		} catch (AddressException e) {
			// ...
		} catch (MessagingException e) {
			// ...
		}
	}

	private String generatePassword(int n) {
	    char[] pw = new char[n];
	    int c  = 'A';
	    int  r1 = 0;
	    for (int i=0; i < n; i++)
	    {
	      r1 = (int)(Math.random() * 3);
	      switch(r1) {
	        case 0: c = '0' +  (int)(Math.random() * 10); break;
	        case 1: c = 'a' +  (int)(Math.random() * 26); break;
	        case 2: c = 'A' +  (int)(Math.random() * 26); break;
	      }
	      pw[i] = (char)c;
	    }
	    return new String(pw);
	}
}
